﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace CCWP7.Model.Parser
{
    public class XmlParser : IXmlParser
    {
        static readonly XName nCruiseControl = "CruiseControl";
        static readonly XName nProjects = "Projects";
        static readonly XName nProject = "Project";
        static readonly XName nQueues = "Queues";
        static readonly XName nQueue = "Queue";

        public IServerReport Parse(string xml)
        {
            if (String.IsNullOrEmpty(xml))
                throw new ArgumentException("xml is null or empty.", "xml");

            var document = XDocument.Parse(xml);

            return ParseDocument(document);
        }
        
        public IServerReport Parse(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException("stream", "stream is null.");

            var document = XDocument.Load(stream);

            return ParseDocument(document);
        }

        IServerReport ParseDocument(XDocument document)
        {
            var root = document.Root;

            if (root.Name != nCruiseControl)
                throw new ArgumentException("Report root element has wrong name: " + root.Name);

            return new ServerReport
            {
                Projects = ParseProjects(root).ToArray(),
                Queues = ParseQueues(root).ToArray()
            };
        }

        IEnumerable<IProjectReport> ParseProjects(XElement root)
        {
            var projects = root.Element(nProjects);

            if (projects == null)
                return Enumerable.Empty<IProjectReport>();

            // <Project name="CCNet" category="" activity="Sleeping" status="Running" lastBuildStatus="Success" lastBuildLabel="1.6.7784.1" lastBuildTime="2010-11-22T13:41:43.5028812-06:00" 
            // nextBuildTime="2010-11-23T04:07:41.7685062-06:00" webUrl="http://ccnetlive.thoughtworks.com/ccnet/server/local/project/CCNet/ViewLatestBuildReport.aspx" buildStage="" serverName="CCNETLIVE" />

            return from p in projects.Elements(nProject)
                   select new ProjectReport
                   {
                       Name = (string) p.Attribute("name"),
                       Category = (string) p.Attribute("category"),
                       Activity = (string) p.Attribute("activity"),
                       Status = (string) p.Attribute("status"),
                       LastBuildStatus = (string) p.Attribute("lastBuildStatus"),
                       LastBuildLabel = (string)p.Attribute("lastBuildLabel"),
                       //LastBuildTime = DateTime.Parse((string)p.Attribute("lastBuildTime")),
                       //NextBuildTime = DateTime.Parse((string)p.Attribute("nextBuildTime")),
                       WebUrl = (string) p.Attribute("webUrl"),
                       BuildStage = (string) p.Attribute("buildStage"),
                       ServerName = (string) p.Attribute("serverName"),
                   } as IProjectReport;
        }

        IEnumerable<IQueueReport> ParseQueues(XElement root)
        {
            var projects = root.Element(nQueues);

            if (projects == null)
                return Enumerable.Empty<IQueueReport>();

            return from p in projects.Elements(nQueue)
                   select new QueueReport
                   {
                       Name = (string)p.Attribute("name"),
                   } as IQueueReport;

        }
    }
}
